package cn.woochen.mvvmframe.config.ext

import androidx.lifecycle.viewModelScope
import cn.woochen.comlib.BaseViewModel
import cn.woochen.comlib.config.RetrofitUtil
import cn.woochen.mvvmframe.config.ApiService
import cn.woochen.mvvmframe.config.status.*
import com.google.gson.GsonBuilder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import okhttp3.MediaType
import okhttp3.RequestBody

val BaseViewModel.rxApi: ApiService by lazy {
    RetrofitUtil.getInstance().retrofit?.create(ApiService::class.java)!!
}

fun BaseViewModel.getRequestBody(map: MutableMap<String, Any>? = null): RequestBody {
    val finalMap: MutableMap<String, Any>?
    if (map == null) {
        finalMap = mutableMapOf()
    } else finalMap = map
    val toJson = GsonBuilder().disableHtmlEscaping().create().toJson(finalMap)
    return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), toJson)
}


/**
 * 默认回调处理
 * @param T  TestBean
 * @param block 请求体方法
 * @param resultState 请求回调的ResultState数据
 * @param isShowDialog 是否显示加载框
 * @param loadingMessage 加载框提示内容
 * @param extParams 额外请求参数字段
 * @param canCancel 是否可以取消 true-随组件生命周期取消 false-全局（跟随Application声明周期）生效
 */
fun <T> BaseViewModel.request(block: suspend () -> BaseBean<T>, resultState: MutableSharedFlow<ResultState<T>>, isShowDialog: Boolean = false, loadingMessage: String = "加载中", extParams: Any = "", canCancel: Boolean = true): Job {
    if (canCancel) {
        return viewModelScope.launch {
            runCatching {
                if (isShowDialog) loadingChange.showDialog.emit(loadingMessage)
                block()
            }.onSuccess {
                loadingChange.dismissDialog.emit("")
                resultState.paresResult(it, extParams)
            }.onFailure {
                loadingChange.dismissDialog.emit("")
                resultState.paresException(it, extParams)
            }
        }
    } else {
        return applicationScope.launch {
            runCatching {
                block()
            }.onSuccess {
                resultState.paresResult(it, extParams)
            }.onFailure {
                resultState.paresException(it, extParams)
            }
        }
    }

}


/**
 * 自定义请求回调，直接回调
 */
fun <T> BaseViewModel.request(block: suspend () -> BaseBean<T>, suc: ((T?, String, String, Any) -> Unit)? = null, fail: ((CustomException, Any) -> Unit)? = null, isShowDialog: Boolean = false, loadingMessage: String = "加载中", extParams: Any = ""): Job {
    return viewModelScope.launch {
        runCatching {
            if (isShowDialog) loadingChange.showDialog.emit(loadingMessage)
            block()
        }.onSuccess {
            loadingChange.dismissDialog.emit("")
            suc?.invoke(it.data, it.errorCode, it.errorMsg, extParams)
        }.onFailure {
            loadingChange.dismissDialog.emit("")
            if (it is CustomException) {
                fail?.invoke(it, extParams)
            } else {
                val e = CustomException(it)
                ErrorCodeHandleHelper.exceptionCodeHandle(e)
                fail?.invoke(e, extParams)
            }
        }
    }
}

val applicationScope by lazy {
    CoroutineScope(SupervisorJob())
}




